import 'dart:collection';

import 'package:flutter/material.dart';
import 'package:flutter_shop/res/colors.dart';
import 'package:flutter_shop/widget/tree_select/tree_item_widget.dart';
import 'package:flutter_shop/widget/tree_select/tree_node.dart';
import 'package:flutter_shop/widget/water_click.dart';

/// Title:树形选择widget  <br/>
/// Description: <br/>
/// author:xiemiao <br/>
/// date: 2020-04-16  <br/>
/// version 1.0 <br/>
class TreeSelect extends StatefulWidget {
  ///数据源
  final List<TreeNode> list;

  ///控制器
  final TreeSelectController controller;

  ///是否关联选择
  final bool isLinkSelect;

  ///checkbox点击监听
  final Function(TreeNode) checkClick;

  ///设置默认展开层级
  final int expandLevel;

  TreeSelect(
    this.list, {
    Key key,
    this.controller,
    this.isLinkSelect = false,
    this.checkClick,
    this.expandLevel = 0,
  }) : super(key: key);

  @override
  _TreeSelectState createState() => _TreeSelectState();
}

class _TreeSelectState extends State<TreeSelect> {
  List<TreeNode> _mDatas;

  @override
  void initState() {
    super.initState();
    _mDatas = widget.list;

    //初始化数据层级(为了设置层级间距)
    _initDataLevel();

    //设置默认展开层级
    _initExpandLevel();
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: ListView.builder(
        itemCount: _mDatas.length,
        itemBuilder: (context, index) => WaterClick(
          fillColor: CommonColors.white,
          onPressed: () {
            //展开或收起
            _expandOrCollapse(index);

            //如果是叶子节点,并且可以选择,就选
            TreeNode treeNode = _mDatas[index];
            if (treeNode.isLeaf() && treeNode.isCanCheck()) {
              _changeCheckStatus(treeNode);
            }
          },
          child: TreeItemWidget(
            _mDatas[index],
            checkboxClick: (item) {
              TreeNode treeNode = _mDatas[index];
              //改变选择状态
              _changeCheckStatus(treeNode);
            },
          ),
        ),
      ),
    );
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // 绑定状态
    widget.controller?._bindState(this);
  }

  ///获取半选择集合
  List<TreeNode> getHalfSelectedList() {
    return getListByCheckStatus(TreeNode.CHECK_STATUS_ARR[2]);
  }

  ///获取已选择集合
  List<TreeNode> getSelectedList() {
    return getListByCheckStatus(TreeNode.CHECK_STATUS_ARR[1]);
  }

  ///获取集合通过选择状态
  List<TreeNode> getListByCheckStatus(String checkStatus) {
    List<TreeNode> selectedList = List();
    //递归遍历根节点,获取指定状态节点
    _mDatas.forEach((element) {
      //如果父节点是空,说明是根节点
      if (element.parentTreeNode == null) {
        if (element.checkStatus == checkStatus && element.isCanCheck()) {
          selectedList.add(element);
        }
        _getAllByCheckStatus(selectedList, element, checkStatus);
      }
    });
    return selectedList;
  }

  ///递归获取指定状态的节点
  void _getAllByCheckStatus(List<TreeNode> selectedList, TreeNode treeNode, String checkStatus) {
    List<TreeNode> children = treeNode.get_children();
    if (children != null && children.isNotEmpty) {
      children.forEach((element) {
        if (element.checkStatus == checkStatus && element.isCanCheck()) {
          selectedList.add(element);
        }
        _getAllByCheckStatus(selectedList, element, checkStatus);
      });
    }
  }

  ///初始化数据层级(为了设置层级边界)
  void _initDataLevel() {
    //设置数据层级与父子关系
    _mDatas.forEach((treeNode) {
      treeNode.level = 0;
      _setParentAndLevel(treeNode);
    });
  }

  ///设置数据层级与父子关系
  void _setParentAndLevel(TreeNode treeNode) {
    int level = treeNode.level;
    List<TreeNode> children = treeNode.get_children();

    children.forEach((child) {
      child.level = level + 1;
      child.parentTreeNode = treeNode;
      _setParentAndLevel(child);
    });
  }

  ///初始化默认展开层级
  void _initExpandLevel() {
    for (int i = 0; i < _mDatas.length; i++) {
      TreeNode treeNode = _mDatas[i];
      List<TreeNode> children = treeNode.get_children();
      if (children != null && children.isNotEmpty && treeNode.level < widget.expandLevel) {
        _mDatas.insertAll(i + 1, children);
        treeNode.isExpand = true;
      }
    }
  }

  ///展开或收缩用户点击的条目
  void _expandOrCollapse(int position) {
    TreeNode node = _mDatas[position];
    if (node != null && !node.isLeaf()) {
      //不是叶子节点
      bool isExpand = node.isExpand;
      if (isExpand) {
        //如果是展开状态,就收缩
        List<TreeNode> nodeList = node.get_children();
        TreeNode tmp = null;
        //遍历子节点统一收缩
        for (int i = 0; i < nodeList.length; i++) {
          tmp = nodeList[i];
          if (tmp.isExpand) {
            _collapse(tmp, position + 1);
          }
          //从集合移除子节点
          _mDatas.removeAt(position + 1);
        }
      } else {
        //如果是收缩状态,就展开
        //添加子节点到集合
        _mDatas.insertAll(position + 1, node.get_children());
      }
      node.isExpand = !isExpand;

      _updateState();
    }
  }

  ///收缩子节点
  void _collapse(TreeNode node, int position) {
    node.isExpand = false;
    List<TreeNode> nodes = node.get_children();
    TreeNode tmp = null;
    for (int i = 0; i < nodes.length; i++) {
      tmp = nodes[i];
      if (tmp.isExpand) {
        _collapse(tmp, position + 1);
      }
      _mDatas.removeAt(position + 1);
    }
  }

  ///改变选择状态
  void _changeCheckStatus(TreeNode treeNode) {
    if (widget.checkClick != null) {
      widget.checkClick(treeNode);
    }

    //如果关联选择
    if (widget.isLinkSelect) {
      if (treeNode.checkStatus == TreeNode.CHECK_STATUS_ARR[0]) {
        //未选

        treeNode.checkStatus = TreeNode.CHECK_STATUS_ARR[1];
        //关联改变孩子状态
        _changeChildNodeState(treeNode, treeNode.checkStatus);
      } else if (treeNode.checkStatus == TreeNode.CHECK_STATUS_ARR[1]) {
        //已选

        treeNode.checkStatus = TreeNode.CHECK_STATUS_ARR[0];
        //关联改变孩子状态
        _changeChildNodeState(treeNode, treeNode.checkStatus);
      } else if (treeNode.checkStatus == TreeNode.CHECK_STATUS_ARR[2]) {
        //半选

        treeNode.checkStatus = TreeNode.CHECK_STATUS_ARR[1];
        //关联改变孩子状态
        _changeChildNodeState(treeNode, treeNode.checkStatus);
      }

      //关联改变父节点状态
      _changeParentNodeState(treeNode);
    } else {
      if (treeNode.checkStatus == TreeNode.CHECK_STATUS_ARR[0]) {
        treeNode.checkStatus = TreeNode.CHECK_STATUS_ARR[1];
      } else {
        treeNode.checkStatus = TreeNode.CHECK_STATUS_ARR[0];
      }
    }

    _updateState();
  }

  ///关联改变孩子状态
  void _changeChildNodeState(TreeNode treeNode, String checkStatus) {
    List<TreeNode> children = treeNode.get_children();
    if (children != null && children.isNotEmpty) {
      children.forEach((element) {
        element.checkStatus = checkStatus;
        _changeChildNodeState(element, element.checkStatus);
      });
    }
  }

  ///关联改变父节点状态
  void _changeParentNodeState(TreeNode treeNode) {
    TreeNode parent = treeNode.parentTreeNode;
    if (parent != null) {
      List<TreeNode> children = parent.get_children();
      if (children != null && children.isNotEmpty) {
        //未选孩子数量
        int unCheckedCount = 0;
        //已选孩子数量
        int checkedCount = 0;
        //半选孩子数量
        int halfCheckedCount = 0;
        children.forEach((element) {
          if (element.checkStatus == TreeNode.CHECK_STATUS_ARR[0]) {
            //未选
            unCheckedCount++;
          } else if (element.checkStatus == TreeNode.CHECK_STATUS_ARR[1]) {
            //已选
            checkedCount++;
          } else if (element.checkStatus == TreeNode.CHECK_STATUS_ARR[2]) {
            //半选
            halfCheckedCount++;
          }
        });

        if (checkedCount == children.length) {
          //如果父节点的孩子全都check了,父节点也checked
          parent.checkStatus = TreeNode.CHECK_STATUS_ARR[1];
        } else if (checkedCount > 0 || halfCheckedCount > 0) {
          //如果父节点的孩子有一个选了,或者有一个半选的,父节点就半选
          parent.checkStatus = TreeNode.CHECK_STATUS_ARR[2];
        } else {
          parent.checkStatus = TreeNode.CHECK_STATUS_ARR[0];
        }

        _changeParentNodeState(parent);
      }
    }
  }

  ///更新状态
  void _updateState() {
    if (this.mounted) {
      setState(() {});
    }
  }
}

///树选择控制器
class TreeSelectController {
  _TreeSelectState state;

  _bindState(_TreeSelectState state) {
    this.state = state;
  }

  ///获取已选择节点
  List<TreeNode> getSelectedList() {
    return state?.getSelectedList();
  }

  ///获取半选择集合
  List<TreeNode> getHalfSelectedList() {
    return state?.getHalfSelectedList();
  }
}
